forked from 1b-agent/opencadstudio-upstream
Merge pull request #1517 from mechpanos/fix/windows-printer-properties-freeze
fix(print): open the driver's printing preferences without blocking the event loop
This commit is contained in:
commit
1a7e372f24
24 files changed
+35
-166
No files matched your search
@@ -5277,8 +5277,6 @@ plot =
|
||||
.this-printer-reports-no-driver-options = This printer reports no driver options.
|
||||
.could-not-read-the-printer-s-options-error = Could not read the printer's options: __ocs_fmt_0__
|
||||
.reading-the-printer-s-options = Reading the printer's options…
|
||||
.printing-preferences-saved-for-printer = Printing preferences saved for __ocs_fmt_0__.
|
||||
.printing-preferences-unchanged = Printing preferences unchanged.
|
||||
.printer-properties = Printer properties
|
||||
.merge-overlapping-lines = دمج الخطوط المتداخلة
|
||||
.object-lineweights = سماكات خطوط الكائنات
|
||||
|
||||
@@ -5265,8 +5265,6 @@ plot =
|
||||
.this-printer-reports-no-driver-options = This printer reports no driver options.
|
||||
.could-not-read-the-printer-s-options-error = Could not read the printer's options: __ocs_fmt_0__
|
||||
.reading-the-printer-s-options = Reading the printer's options…
|
||||
.printing-preferences-saved-for-printer = Printing preferences saved for __ocs_fmt_0__.
|
||||
.printing-preferences-unchanged = Printing preferences unchanged.
|
||||
.printer-properties = Printer properties
|
||||
.merge-overlapping-lines = Обедини припокриващи се линии
|
||||
.object-lineweights = Дебелини на линии на обект
|
||||
|
||||
@@ -5262,8 +5262,6 @@ plot =
|
||||
.this-printer-reports-no-driver-options = This printer reports no driver options.
|
||||
.could-not-read-the-printer-s-options-error = Could not read the printer's options: __ocs_fmt_0__
|
||||
.reading-the-printer-s-options = Reading the printer's options…
|
||||
.printing-preferences-saved-for-printer = Printing preferences saved for __ocs_fmt_0__.
|
||||
.printing-preferences-unchanged = Printing preferences unchanged.
|
||||
.printer-properties = Printer properties
|
||||
.merge-overlapping-lines = Sloučit překrývající se čáry
|
||||
.object-lineweights = Tloušťky čar objektů
|
||||
|
||||
@@ -5263,8 +5263,6 @@ plot =
|
||||
.this-printer-reports-no-driver-options = This printer reports no driver options.
|
||||
.could-not-read-the-printer-s-options-error = Could not read the printer's options: __ocs_fmt_0__
|
||||
.reading-the-printer-s-options = Reading the printer's options…
|
||||
.printing-preferences-saved-for-printer = Printing preferences saved for __ocs_fmt_0__.
|
||||
.printing-preferences-unchanged = Printing preferences unchanged.
|
||||
.printer-properties = Printer properties
|
||||
.merge-overlapping-lines = Zusammenführung überlappender Leitungen
|
||||
.object-lineweights = Objektliniengewichte
|
||||
|
||||
@@ -5265,8 +5265,6 @@ plot =
|
||||
.this-printer-reports-no-driver-options = Ο εκτυπωτής δεν αναφέρει επιλογές driver.
|
||||
.could-not-read-the-printer-s-options-error = Αδυναμία ανάγνωσης των επιλογών του εκτυπωτή: __ocs_fmt_0__
|
||||
.reading-the-printer-s-options = Ανάγνωση των επιλογών του εκτυπωτή…
|
||||
.printing-preferences-saved-for-printer = Οι προτιμήσεις εκτύπωσης αποθηκεύτηκαν για τον εκτυπωτή __ocs_fmt_0__.
|
||||
.printing-preferences-unchanged = Οι προτιμήσεις εκτύπωσης δεν άλλαξαν.
|
||||
.printer-properties = Ιδιότητες εκτυπωτή
|
||||
.merge-overlapping-lines = Συγχώνευση επικαλυπτόμενων γραμμών
|
||||
.object-lineweights = Πάχη γραμμών αντικειμένων
|
||||
|
||||
@@ -5266,8 +5266,6 @@ plot =
|
||||
.this-printer-reports-no-driver-options = This printer reports no driver options.
|
||||
.could-not-read-the-printer-s-options-error = Could not read the printer's options: __ocs_fmt_0__
|
||||
.reading-the-printer-s-options = Reading the printer's options…
|
||||
.printing-preferences-saved-for-printer = Printing preferences saved for __ocs_fmt_0__.
|
||||
.printing-preferences-unchanged = Printing preferences unchanged.
|
||||
.printer-properties = Printer properties
|
||||
.merge-overlapping-lines = Merge overlapping lines
|
||||
.object-lineweights = Object lineweights
|
||||
|
||||
@@ -5265,8 +5265,6 @@ plot =
|
||||
.this-printer-reports-no-driver-options = This printer reports no driver options.
|
||||
.could-not-read-the-printer-s-options-error = Could not read the printer's options: __ocs_fmt_0__
|
||||
.reading-the-printer-s-options = Reading the printer's options…
|
||||
.printing-preferences-saved-for-printer = Printing preferences saved for __ocs_fmt_0__.
|
||||
.printing-preferences-unchanged = Printing preferences unchanged.
|
||||
.printer-properties = Printer properties
|
||||
.merge-overlapping-lines = Fusionar líneas solapadas
|
||||
.object-lineweights = Grosores de línea de objetos
|
||||
|
||||
@@ -5264,8 +5264,6 @@ plot =
|
||||
.this-printer-reports-no-driver-options = This printer reports no driver options.
|
||||
.could-not-read-the-printer-s-options-error = Could not read the printer's options: __ocs_fmt_0__
|
||||
.reading-the-printer-s-options = Reading the printer's options…
|
||||
.printing-preferences-saved-for-printer = Printing preferences saved for __ocs_fmt_0__.
|
||||
.printing-preferences-unchanged = Printing preferences unchanged.
|
||||
.printer-properties = Printer properties
|
||||
.merge-overlapping-lines = Yhdistä päällekkäiset rivit
|
||||
.object-lineweights = Objektin viivan painot
|
||||
|
||||
@@ -5265,8 +5265,6 @@ plot =
|
||||
.this-printer-reports-no-driver-options = This printer reports no driver options.
|
||||
.could-not-read-the-printer-s-options-error = Could not read the printer's options: __ocs_fmt_0__
|
||||
.reading-the-printer-s-options = Reading the printer's options…
|
||||
.printing-preferences-saved-for-printer = Printing preferences saved for __ocs_fmt_0__.
|
||||
.printing-preferences-unchanged = Printing preferences unchanged.
|
||||
.printer-properties = Printer properties
|
||||
.merge-overlapping-lines = Fusionner les lignes qui se chevauchent
|
||||
.object-lineweights = Poids de ligne d'objet
|
||||
|
||||
@@ -5253,8 +5253,6 @@ plot =
|
||||
.this-printer-reports-no-driver-options = This printer reports no driver options.
|
||||
.could-not-read-the-printer-s-options-error = Could not read the printer's options: __ocs_fmt_0__
|
||||
.reading-the-printer-s-options = Reading the printer's options…
|
||||
.printing-preferences-saved-for-printer = Printing preferences saved for __ocs_fmt_0__.
|
||||
.printing-preferences-unchanged = Printing preferences unchanged.
|
||||
.printer-properties = Printer properties
|
||||
.merge-overlapping-lines = मर्ज ओवरलैपिंग लाइन
|
||||
.object-lineweights = ऑब्जेक्ट लाइनवेट
|
||||
|
||||
@@ -5264,8 +5264,6 @@ plot =
|
||||
.this-printer-reports-no-driver-options = This printer reports no driver options.
|
||||
.could-not-read-the-printer-s-options-error = Could not read the printer's options: __ocs_fmt_0__
|
||||
.reading-the-printer-s-options = Reading the printer's options…
|
||||
.printing-preferences-saved-for-printer = Printing preferences saved for __ocs_fmt_0__.
|
||||
.printing-preferences-unchanged = Printing preferences unchanged.
|
||||
.printer-properties = Printer properties
|
||||
.merge-overlapping-lines = Egyesítse az átfedő vonalakat
|
||||
.object-lineweights = Objektumvonalvastagságok
|
||||
|
||||
@@ -5264,8 +5264,6 @@ plot =
|
||||
.this-printer-reports-no-driver-options = This printer reports no driver options.
|
||||
.could-not-read-the-printer-s-options-error = Could not read the printer's options: __ocs_fmt_0__
|
||||
.reading-the-printer-s-options = Reading the printer's options…
|
||||
.printing-preferences-saved-for-printer = Printing preferences saved for __ocs_fmt_0__.
|
||||
.printing-preferences-unchanged = Printing preferences unchanged.
|
||||
.printer-properties = Printer properties
|
||||
.merge-overlapping-lines = Unisci linee sovrapposte
|
||||
.object-lineweights = Spessori linea degli oggetti
|
||||
|
||||
@@ -5253,8 +5253,6 @@ plot =
|
||||
.this-printer-reports-no-driver-options = This printer reports no driver options.
|
||||
.could-not-read-the-printer-s-options-error = Could not read the printer's options: __ocs_fmt_0__
|
||||
.reading-the-printer-s-options = Reading the printer's options…
|
||||
.printing-preferences-saved-for-printer = Printing preferences saved for __ocs_fmt_0__.
|
||||
.printing-preferences-unchanged = Printing preferences unchanged.
|
||||
.printer-properties = Printer properties
|
||||
.merge-overlapping-lines = 重複線を結合
|
||||
.object-lineweights = オブジェクトの線の太さ
|
||||
|
||||
@@ -5264,8 +5264,6 @@ plot =
|
||||
.this-printer-reports-no-driver-options = This printer reports no driver options.
|
||||
.could-not-read-the-printer-s-options-error = Could not read the printer's options: __ocs_fmt_0__
|
||||
.reading-the-printer-s-options = Reading the printer's options…
|
||||
.printing-preferences-saved-for-printer = Printing preferences saved for __ocs_fmt_0__.
|
||||
.printing-preferences-unchanged = Printing preferences unchanged.
|
||||
.printer-properties = Printer properties
|
||||
.merge-overlapping-lines = 겹치는 선 병합
|
||||
.object-lineweights = 객체 선가중치
|
||||
|
||||
@@ -5263,8 +5263,6 @@ plot =
|
||||
.this-printer-reports-no-driver-options = This printer reports no driver options.
|
||||
.could-not-read-the-printer-s-options-error = Could not read the printer's options: __ocs_fmt_0__
|
||||
.reading-the-printer-s-options = Reading the printer's options…
|
||||
.printing-preferences-saved-for-printer = Printing preferences saved for __ocs_fmt_0__.
|
||||
.printing-preferences-unchanged = Printing preferences unchanged.
|
||||
.printer-properties = Printer properties
|
||||
.merge-overlapping-lines = Overlaplijnen samenvoegen
|
||||
.object-lineweights = Objectlijndiktes
|
||||
|
||||
@@ -5264,8 +5264,6 @@ plot =
|
||||
.this-printer-reports-no-driver-options = This printer reports no driver options.
|
||||
.could-not-read-the-printer-s-options-error = Could not read the printer's options: __ocs_fmt_0__
|
||||
.reading-the-printer-s-options = Reading the printer's options…
|
||||
.printing-preferences-saved-for-printer = Printing preferences saved for __ocs_fmt_0__.
|
||||
.printing-preferences-unchanged = Printing preferences unchanged.
|
||||
.printer-properties = Printer properties
|
||||
.merge-overlapping-lines = Połącz nakładające się linie
|
||||
.object-lineweights = Szerokości linii obiektu
|
||||
|
||||
@@ -5265,8 +5265,6 @@ plot =
|
||||
.this-printer-reports-no-driver-options = This printer reports no driver options.
|
||||
.could-not-read-the-printer-s-options-error = Could not read the printer's options: __ocs_fmt_0__
|
||||
.reading-the-printer-s-options = Reading the printer's options…
|
||||
.printing-preferences-saved-for-printer = Printing preferences saved for __ocs_fmt_0__.
|
||||
.printing-preferences-unchanged = Printing preferences unchanged.
|
||||
.printer-properties = Printer properties
|
||||
.merge-overlapping-lines = Mesclar linhas sobrepostas
|
||||
.object-lineweights = Espessuras de linha dos objetos
|
||||
|
||||
@@ -5266,8 +5266,6 @@ plot =
|
||||
.this-printer-reports-no-driver-options = This printer reports no driver options.
|
||||
.could-not-read-the-printer-s-options-error = Could not read the printer's options: __ocs_fmt_0__
|
||||
.reading-the-printer-s-options = Reading the printer's options…
|
||||
.printing-preferences-saved-for-printer = Printing preferences saved for __ocs_fmt_0__.
|
||||
.printing-preferences-unchanged = Printing preferences unchanged.
|
||||
.printer-properties = Printer properties
|
||||
.merge-overlapping-lines = Слияние пересекающихся линий
|
||||
.object-lineweights = Весы для объектов
|
||||
|
||||
@@ -5205,8 +5205,6 @@ plot =
|
||||
.this-printer-reports-no-driver-options = This printer reports no driver options.
|
||||
.could-not-read-the-printer-s-options-error = Could not read the printer's options: __ocs_fmt_0__
|
||||
.reading-the-printer-s-options = Reading the printer's options…
|
||||
.printing-preferences-saved-for-printer = Printing preferences saved for __ocs_fmt_0__.
|
||||
.printing-preferences-unchanged = Printing preferences unchanged.
|
||||
.printer-properties = Printer properties
|
||||
.merge-overlapping-lines = Çakışan çizgileri birleştir
|
||||
.object-lineweights = Nesne çizgi kalınlıkları
|
||||
|
||||
@@ -5248,8 +5248,6 @@ plot =
|
||||
.this-printer-reports-no-driver-options = This printer reports no driver options.
|
||||
.could-not-read-the-printer-s-options-error = Could not read the printer's options: __ocs_fmt_0__
|
||||
.reading-the-printer-s-options = Reading the printer's options…
|
||||
.printing-preferences-saved-for-printer = Printing preferences saved for __ocs_fmt_0__.
|
||||
.printing-preferences-unchanged = Printing preferences unchanged.
|
||||
.printer-properties = Printer properties
|
||||
.merge-overlapping-lines = 合并重叠线
|
||||
.object-lineweights = 对象线宽
|
||||
|
||||
@@ -5260,8 +5260,6 @@ plot =
|
||||
.this-printer-reports-no-driver-options = This printer reports no driver options.
|
||||
.could-not-read-the-printer-s-options-error = Could not read the printer's options: __ocs_fmt_0__
|
||||
.reading-the-printer-s-options = Reading the printer's options…
|
||||
.printing-preferences-saved-for-printer = Printing preferences saved for __ocs_fmt_0__.
|
||||
.printing-preferences-unchanged = Printing preferences unchanged.
|
||||
.printer-properties = Printer properties
|
||||
.merge-overlapping-lines = 合併重疊線
|
||||
.object-lineweights = 物件線寬
|
||||
|
||||
+16
-39
@@ -4416,9 +4416,9 @@ impl OpenCADStudio {
|
||||
///
|
||||
/// On CUPS platforms (Linux, macOS) the driver's options are listed in an
|
||||
/// in-line editor and applied to every job for that printer through
|
||||
/// `lp -o`. On Windows the driver's own document-properties sheet is
|
||||
/// shown and its result stored as the printer's preferences, which the
|
||||
/// print job honours. Without a named printer, or where the options
|
||||
/// `lp -o`. On Windows the system opens the driver's own printing
|
||||
/// preferences in its own process, and the print job honours what the
|
||||
/// user saves there. Without a named printer, or where the options
|
||||
/// cannot be listed, the platform's printer settings open instead.
|
||||
fn on_printer_properties(&mut self) -> Task<Message> {
|
||||
// "Default" is a real printer: its preferences sheet is the one to
|
||||
@@ -4429,12 +4429,18 @@ impl OpenCADStudio {
|
||||
.clone()
|
||||
.or_else(|| self.plot_dialog.default_printer.clone());
|
||||
let Some(printer) = chosen.filter(|_| !self.plot_dialog.to_file) else {
|
||||
self.open_printer_settings_fallback();
|
||||
self.open_printer_settings(None);
|
||||
return Task::none();
|
||||
};
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
return self.edit_windows_printer_preferences(printer);
|
||||
// The driver's sheet is modal: it pumps messages itself until the
|
||||
// user closes it. Hosted on our event-loop thread it starves the
|
||||
// loop it is sharing, so the window stops painting and a core
|
||||
// spins. The system's own preferences process pumps its own
|
||||
// messages instead, which leaves ours free.
|
||||
self.open_printer_settings(Some(&printer));
|
||||
return Task::none();
|
||||
}
|
||||
#[allow(unreachable_code)]
|
||||
{
|
||||
@@ -4456,40 +4462,11 @@ impl OpenCADStudio {
|
||||
}
|
||||
}
|
||||
|
||||
/// The driver's document-properties sheet, owned by the main window so
|
||||
/// it sits on top of the plot dialog.
|
||||
#[cfg(target_os = "windows")]
|
||||
fn edit_windows_printer_preferences(&mut self, printer: String) -> Task<Message> {
|
||||
let Some(window) = self.main_window else {
|
||||
self.open_printer_settings_fallback();
|
||||
return Task::none();
|
||||
};
|
||||
iced::window::run(window, move |w| {
|
||||
use iced::window::raw_window_handle::RawWindowHandle;
|
||||
let owner = match w.window_handle().ok().map(|h| h.as_raw()) {
|
||||
Some(RawWindowHandle::Win32(handle)) => handle.hwnd.get(),
|
||||
_ => 0,
|
||||
};
|
||||
match crate::io::print_to_printer::edit_printer_preferences(&printer, owner) {
|
||||
Ok(true) => Ok(crate::tf!("Printing preferences saved for {printer}.").into_owned()),
|
||||
Ok(false) => Ok(crate::t!("Printing preferences unchanged.").into_owned()),
|
||||
Err(error) => Err(error),
|
||||
}
|
||||
})
|
||||
.then(|result| {
|
||||
Task::done(Message::BackgroundIoFinished(
|
||||
result.map(|message| message),
|
||||
false,
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
/// The platform's printer settings surface: a settings panel on Linux,
|
||||
/// the printers control panel on Windows, System Settings on macOS.
|
||||
fn open_printer_settings_fallback(&mut self) {
|
||||
match crate::io::print_to_printer::open_printer_properties(
|
||||
self.plot_dialog.printer.as_deref(),
|
||||
) {
|
||||
/// The platform's printer settings surface: the driver's printing
|
||||
/// preferences for `printer`, or — without one — a settings panel on
|
||||
/// Linux, the printers control panel on Windows, System Settings on macOS.
|
||||
fn open_printer_settings(&mut self, printer: Option<&str>) {
|
||||
match crate::io::print_to_printer::open_printer_properties(printer) {
|
||||
Ok(()) => self
|
||||
.command_line
|
||||
.push_info(crate::t!("Opened printer properties.").as_ref()),
|
||||
|
||||
+19
-83
@@ -1593,6 +1593,25 @@ mod printer_properties_tests {
|
||||
}
|
||||
}
|
||||
|
||||
/// `printui` parses the raw command line itself, so a name that reaches it
|
||||
/// split over several arguments matches no printer and it exits 0 without
|
||||
/// drawing anything — a failure with nothing to show the user. The name
|
||||
/// has to stay a single argument, directly after `/n`. The verb matters
|
||||
/// too: `/e` is printing preferences, `/p` the device's admin sheet.
|
||||
#[cfg(target_os = "windows")]
|
||||
#[test]
|
||||
fn windows_preferences_keep_the_printer_name_in_one_argument() {
|
||||
for name in ["Office Printer", "Wide Format Plotter 1200", "Εκτυπωτής γραφείου"] {
|
||||
let (program, args) = printer_properties_command(Some(name));
|
||||
assert_eq!(program, "rundll32.exe");
|
||||
assert!(args.contains(&"/e".to_string()), "{args:?} must ask for preferences");
|
||||
assert!(!args.contains(&"/p".to_string()), "{args:?} must not ask for properties");
|
||||
let flag = args.iter().position(|arg| arg == "/n").expect("/n introduces the name");
|
||||
assert_eq!(args.get(flag + 1).map(String::as_str), Some(name), "{args:?}");
|
||||
assert_eq!(args.iter().filter(|arg| arg.as_str() == name).count(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[test]
|
||||
fn macos_opens_print_settings() {
|
||||
@@ -1797,89 +1816,6 @@ pub fn open_desktop_printer_settings(printer: Option<&str>) -> Result<(), String
|
||||
.map_err(|error| format!("Could not open printer settings: {error}"))
|
||||
}
|
||||
|
||||
/// Show the driver's own document-properties sheet for `printer`, owned by
|
||||
/// the window `owner` (an `HWND`, 0 for none), and on OK store the result as
|
||||
/// the user's printing preferences for that printer — which is what the
|
||||
/// print job then honours. Returns `Ok(false)` when the user cancelled.
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn edit_printer_preferences(printer: &str, owner: isize) -> Result<bool, String> {
|
||||
use windows_sys::Win32::Graphics::Gdi::DEVMODEW;
|
||||
use windows_sys::Win32::Graphics::Printing::{
|
||||
ClosePrinter, DocumentPropertiesW, OpenPrinterW, SetPrinterW, PRINTER_HANDLE,
|
||||
PRINTER_INFO_9W,
|
||||
};
|
||||
// winspool.h: DM_OUT_BUFFER = DM_COPY, DM_IN_PROMPT = DM_PROMPT,
|
||||
// DM_IN_BUFFER = DM_MODIFY.
|
||||
const DM_OUT_BUFFER: u32 = 2;
|
||||
const DM_IN_PROMPT: u32 = 4;
|
||||
const DM_IN_BUFFER: u32 = 8;
|
||||
const IDOK: i32 = 1;
|
||||
|
||||
let name: Vec<u16> = printer.encode_utf16().chain(std::iter::once(0)).collect();
|
||||
let mut handle = PRINTER_HANDLE {
|
||||
Value: std::ptr::null_mut(),
|
||||
};
|
||||
// SAFETY: `name` is NUL-terminated and outlives the call; a null default
|
||||
// asks for PRINTER_ACCESS_USE, enough for per-user preferences.
|
||||
if unsafe { OpenPrinterW(name.as_ptr(), &mut handle, std::ptr::null()) } == 0 {
|
||||
return Err(format!("Could not open printer \"{printer}\""));
|
||||
}
|
||||
let owner = owner as windows_sys::Win32::Foundation::HWND;
|
||||
let outcome = (|| {
|
||||
// SAFETY: with null buffers the call only reports the DEVMODE size.
|
||||
let size = unsafe {
|
||||
DocumentPropertiesW(owner, handle, name.as_ptr(), std::ptr::null_mut(), std::ptr::null(), 0)
|
||||
};
|
||||
if size <= 0 {
|
||||
return Err(format!("Printer \"{printer}\" reports no document properties"));
|
||||
}
|
||||
// DEVMODEW is u16-aligned; a u16 buffer keeps the cast sound.
|
||||
let words = (size as usize).div_ceil(2);
|
||||
let mut current = vec![0u16; words];
|
||||
let mut edited = vec![0u16; words];
|
||||
// SAFETY: both buffers hold `size` bytes as the driver requested.
|
||||
let fetched = unsafe {
|
||||
DocumentPropertiesW(
|
||||
owner,
|
||||
handle,
|
||||
name.as_ptr(),
|
||||
current.as_mut_ptr().cast::<DEVMODEW>(),
|
||||
std::ptr::null(),
|
||||
DM_OUT_BUFFER,
|
||||
)
|
||||
};
|
||||
if fetched < 0 {
|
||||
return Err(format!("Could not read the preferences of \"{printer}\""));
|
||||
}
|
||||
edited.copy_from_slice(¤t);
|
||||
// SAFETY: as above; DM_IN_PROMPT runs the driver's modal sheet.
|
||||
let response = unsafe {
|
||||
DocumentPropertiesW(
|
||||
owner,
|
||||
handle,
|
||||
name.as_ptr(),
|
||||
edited.as_mut_ptr().cast::<DEVMODEW>(),
|
||||
current.as_ptr().cast::<DEVMODEW>(),
|
||||
DM_IN_BUFFER | DM_IN_PROMPT | DM_OUT_BUFFER,
|
||||
)
|
||||
};
|
||||
if response != IDOK {
|
||||
return Ok(false);
|
||||
}
|
||||
let info = PRINTER_INFO_9W {
|
||||
pDevMode: edited.as_mut_ptr().cast::<DEVMODEW>(),
|
||||
};
|
||||
// SAFETY: level 9 takes a PRINTER_INFO_9W; the DEVMODE outlives the call.
|
||||
if unsafe { SetPrinterW(handle, 9, (&info as *const PRINTER_INFO_9W).cast::<u8>(), 0) } == 0 {
|
||||
return Err(format!("Could not save the preferences of \"{printer}\""));
|
||||
}
|
||||
Ok(true)
|
||||
})();
|
||||
// SAFETY: `handle` came from OpenPrinterW above.
|
||||
unsafe { ClosePrinter(handle) };
|
||||
outcome
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod driver_option_tests {
|
||||
use super::*;
|
||||
|
||||
@@ -1504,8 +1504,6 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static
|
||||
"This printer reports no driver options." => Some(("plot", "this-printer-reports-no-driver-options")),
|
||||
"Could not read the printer's options: {error}" => Some(("plot", "could-not-read-the-printer-s-options-error")),
|
||||
"Reading the printer's options…" => Some(("plot", "reading-the-printer-s-options")),
|
||||
"Printing preferences saved for {printer}." => Some(("plot", "printing-preferences-saved-for-printer")),
|
||||
"Printing preferences unchanged." => Some(("plot", "printing-preferences-unchanged")),
|
||||
"Printer properties" => Some(("plot", "printer-properties")),
|
||||
"Layout renamed: '{old_name}' → '{new_name}'" => Some(("common", "layout-renamed-old-name-new-name")),
|
||||
"Layouts" => Some(("layout", "layouts")),
|
||||
|
||||
Reference in new issue
Block a user