windows: Fix incorrect button ID setting for TaskDialog (#25391)
Closes #22821 It turns out that on Windows, the `Cancel` button should **always** have a button ID of `2`. Even if the button label is something like "Don't Cancel", when the user presses the `Esc` key, Windows will still report that the button with ID `2` was pressed. Release Notes: - N/A
This commit is contained in:
parent
7a55da58d9
commit
10053e2566
1 changed files with 19 additions and 9 deletions
|
@ -14,7 +14,6 @@ use ::util::ResultExt;
|
||||||
use anyhow::{Context as _, Result};
|
use anyhow::{Context as _, Result};
|
||||||
use async_task::Runnable;
|
use async_task::Runnable;
|
||||||
use futures::channel::oneshot::{self, Receiver};
|
use futures::channel::oneshot::{self, Receiver};
|
||||||
use itertools::Itertools;
|
|
||||||
use raw_window_handle as rwh;
|
use raw_window_handle as rwh;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use windows::{
|
use windows::{
|
||||||
|
@ -577,8 +576,7 @@ impl PlatformWindow for WindowsWindow {
|
||||||
.executor
|
.executor
|
||||||
.spawn(async move {
|
.spawn(async move {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut config;
|
let mut config = TASKDIALOGCONFIG::default();
|
||||||
config = std::mem::zeroed::<TASKDIALOGCONFIG>();
|
|
||||||
config.cbSize = std::mem::size_of::<TASKDIALOGCONFIG>() as _;
|
config.cbSize = std::mem::size_of::<TASKDIALOGCONFIG>() as _;
|
||||||
config.hwndParent = handle;
|
config.hwndParent = handle;
|
||||||
let title;
|
let title;
|
||||||
|
@ -599,19 +597,26 @@ impl PlatformWindow for WindowsWindow {
|
||||||
};
|
};
|
||||||
config.pszWindowTitle = title;
|
config.pszWindowTitle = title;
|
||||||
config.Anonymous1.pszMainIcon = main_icon;
|
config.Anonymous1.pszMainIcon = main_icon;
|
||||||
let instruction = msg.encode_utf16().chain(Some(0)).collect_vec();
|
let instruction = HSTRING::from(msg);
|
||||||
config.pszMainInstruction = PCWSTR::from_raw(instruction.as_ptr());
|
config.pszMainInstruction = PCWSTR::from_raw(instruction.as_ptr());
|
||||||
let hints_encoded;
|
let hints_encoded;
|
||||||
if let Some(ref hints) = detail_string {
|
if let Some(ref hints) = detail_string {
|
||||||
hints_encoded = hints.encode_utf16().chain(Some(0)).collect_vec();
|
hints_encoded = HSTRING::from(hints);
|
||||||
config.pszContent = PCWSTR::from_raw(hints_encoded.as_ptr());
|
config.pszContent = PCWSTR::from_raw(hints_encoded.as_ptr());
|
||||||
};
|
};
|
||||||
|
let mut button_id_map = Vec::with_capacity(answers.len());
|
||||||
let mut buttons = Vec::new();
|
let mut buttons = Vec::new();
|
||||||
let mut btn_encoded = Vec::new();
|
let mut btn_encoded = Vec::new();
|
||||||
for (index, btn_string) in answers.iter().enumerate() {
|
for (index, btn_string) in answers.iter().enumerate() {
|
||||||
let encoded = btn_string.encode_utf16().chain(Some(0)).collect_vec();
|
let encoded = HSTRING::from(btn_string);
|
||||||
|
let button_id = if btn_string == "Cancel" {
|
||||||
|
IDCANCEL.0
|
||||||
|
} else {
|
||||||
|
index as i32 - 100
|
||||||
|
};
|
||||||
|
button_id_map.push(button_id);
|
||||||
buttons.push(TASKDIALOG_BUTTON {
|
buttons.push(TASKDIALOG_BUTTON {
|
||||||
nButtonID: index as _,
|
nButtonID: button_id,
|
||||||
pszButtonText: PCWSTR::from_raw(encoded.as_ptr()),
|
pszButtonText: PCWSTR::from_raw(encoded.as_ptr()),
|
||||||
});
|
});
|
||||||
btn_encoded.push(encoded);
|
btn_encoded.push(encoded);
|
||||||
|
@ -622,9 +627,14 @@ impl PlatformWindow for WindowsWindow {
|
||||||
config.pfCallback = None;
|
config.pfCallback = None;
|
||||||
let mut res = std::mem::zeroed();
|
let mut res = std::mem::zeroed();
|
||||||
let _ = TaskDialogIndirect(&config, Some(&mut res), None, None)
|
let _ = TaskDialogIndirect(&config, Some(&mut res), None, None)
|
||||||
.inspect_err(|e| log::error!("unable to create task dialog: {}", e));
|
.context("unable to create task dialog")
|
||||||
|
.log_err();
|
||||||
|
|
||||||
let _ = done_tx.send(res as usize);
|
let clicked = button_id_map
|
||||||
|
.iter()
|
||||||
|
.position(|&button_id| button_id == res)
|
||||||
|
.unwrap();
|
||||||
|
let _ = done_tx.send(clicked);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue