Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: remove manifest from build.rs and leave it to users #76

Merged
merged 2 commits into from
Jun 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,7 @@ wasm-bindgen-futures = "0.4.19"
name = "simple"
[[example]]
name = "async"
[[example]]
name = "msg-custom-buttons"

[package.metadata.docs.rs]
features = ["file-handle-inner"]

[build-dependencies]
embed-resource = "1.6"
5 changes: 0 additions & 5 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
extern crate embed_resource;

fn main() {
let target = std::env::var("TARGET").unwrap();

Expand All @@ -12,7 +10,4 @@ fn main() {

#[cfg(not(any(feature = "gtk3", feature = "xdg-portal")))]
compile_error!("You need to choose at least one backend: `gtk3` or `xdg-portal` features");

#[cfg(all(target_os = "windows", feature = "common-controls-v6"))]
embed_resource::compile("manifest.rc");
}
2 changes: 2 additions & 0 deletions examples/message-custom-buttons/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/target
Cargo.lock
10 changes: 10 additions & 0 deletions examples/message-custom-buttons/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "message-custom-buttons"
version = "0.1.0"
edition = "2021"

[dependencies]
rfd = {version = "0.9.0", path = "../..", features=["common-controls-v6"]}

[build-dependencies]
embed-resource = "1.6"
File renamed without changes.
6 changes: 6 additions & 0 deletions examples/message-custom-buttons/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
extern crate embed_resource;

fn main() {
#[cfg(target_os = "windows")]
embed_resource::compile("manifest.rc");
}
File renamed without changes.
13 changes: 10 additions & 3 deletions src/backend/gtk3/message_dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,14 @@ impl GtkMessageDialog {
let custom_buttons = match opt.buttons {
MessageButtons::OkCustom(ok_text) => vec![
Some((CString::new(ok_text).unwrap(), gtk_sys::GTK_RESPONSE_OK)),
None
None,
],
MessageButtons::OkCancelCustom(ok_text, cancel_text) => vec![
Some((CString::new(ok_text).unwrap(), gtk_sys::GTK_RESPONSE_OK)),
Some((CString::new(cancel_text).unwrap(), gtk_sys::GTK_RESPONSE_CANCEL)),
Some((
CString::new(cancel_text).unwrap(),
gtk_sys::GTK_RESPONSE_CANCEL,
)),
],
_ => vec![],
};
Expand All @@ -58,7 +61,11 @@ impl GtkMessageDialog {

for custom_button in custom_buttons {
if let Some((custom_button_cstr, response_id)) = custom_button {
gtk_sys::gtk_dialog_add_button(dialog, custom_button_cstr.as_ptr(), response_id);
gtk_sys::gtk_dialog_add_button(
dialog,
custom_button_cstr.as_ptr(),
response_id,
);
}
}

Expand Down
23 changes: 5 additions & 18 deletions src/backend/macos/message_dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,24 +55,11 @@ impl NSAlert {
}

let buttons = match opt.buttons {
MessageButtons::Ok => vec![
"OK".to_owned(),
],
MessageButtons::OkCancel => vec![
"OK".to_owned(),
"Cancel".to_owned(),
],
MessageButtons::YesNo => vec![
"Yes".to_owned(),
"No".to_owned(),
],
MessageButtons::OkCustom(ok_text) => vec![
ok_text,
],
MessageButtons::OkCancelCustom(ok_text, cancel_text) => vec![
ok_text,
cancel_text,
],
MessageButtons::Ok => vec!["OK".to_owned()],
MessageButtons::OkCancel => vec!["OK".to_owned(), "Cancel".to_owned()],
MessageButtons::YesNo => vec!["Yes".to_owned(), "No".to_owned()],
MessageButtons::OkCustom(ok_text) => vec![ok_text],
MessageButtons::OkCancelCustom(ok_text, cancel_text) => vec![ok_text, cancel_text],
};

for button in buttons {
Expand Down
4 changes: 3 additions & 1 deletion src/backend/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,9 @@ impl MessageDialogImpl for MessageDialog {
alert(&text);
true
}
MessageButtons::OkCancel | MessageButtons::YesNo | MessageButtons::OkCancelCustom(_, _) => confirm(&text),
MessageButtons::OkCancel
| MessageButtons::YesNo
| MessageButtons::OkCancelCustom(_, _) => confirm(&text),
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/backend/win_cid/file_dialog/dialog_ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use windows::Win32::{
System::Com::{CoCreateInstance, CoTaskMemFree, CLSCTX_INPROC_SERVER},
UI::Shell::{
Common::COMDLG_FILTERSPEC, FileOpenDialog, FileSaveDialog, IFileDialog, IFileOpenDialog,
IFileSaveDialog, IShellItem, SHCreateItemFromParsingName, FOS_ALLOWMULTISELECT,
FOS_PICKFOLDERS, SIGDN_FILESYSPATH, FILEOPENDIALOGOPTIONS,
IFileSaveDialog, IShellItem, SHCreateItemFromParsingName, FILEOPENDIALOGOPTIONS,
FOS_ALLOWMULTISELECT, FOS_PICKFOLDERS, SIGDN_FILESYSPATH,
},
};

Expand Down
112 changes: 39 additions & 73 deletions src/backend/win_cid/message_dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,18 @@ use crate::message_dialog::{MessageButtons, MessageDialog};
use windows::{
core::PCWSTR,
Win32::{
Foundation::{
HWND,
},
UI::{
WindowsAndMessaging::{
IDOK, IDYES
},
}
Foundation::HWND,
UI::WindowsAndMessaging::{IDOK, IDYES},
},
};

#[cfg(not(feature = "common-controls-v6"))]
use crate::message_dialog::{MessageLevel};
use crate::message_dialog::MessageLevel;

#[cfg(not(feature = "common-controls-v6"))]
use windows::{
Win32::{
UI::{
WindowsAndMessaging::{
MessageBoxW, MB_ICONERROR, MB_ICONINFORMATION, MB_ICONWARNING, MB_OK,
MB_OKCANCEL, MB_YESNO, MESSAGEBOX_STYLE,
},
}
},
use windows::Win32::UI::WindowsAndMessaging::{
MessageBoxW, MB_ICONERROR, MB_ICONINFORMATION, MB_ICONWARNING, MB_OK, MB_OKCANCEL, MB_YESNO,
MESSAGEBOX_STYLE,
};

use raw_window_handle::RawWindowHandle;
Expand All @@ -49,10 +37,7 @@ pub struct WinMessageDialog {
unsafe impl Send for WinMessageDialog {}

fn str_to_vec_u16(str: &str) -> Vec<u16> {
OsStr::new(str)
.encode_wide()
.chain(once(0))
.collect()
OsStr::new(str).encode_wide().chain(once(0)).collect()
}

impl WinMessageDialog {
Expand Down Expand Up @@ -94,18 +79,12 @@ impl WinMessageDialog {
#[cfg(feature = "common-controls-v6")]
pub fn run(mut self) -> bool {
use windows::Win32::{
Foundation::BOOL,
UI::Controls::{
TASKDIALOGCONFIG,
TDF_ALLOW_DIALOG_CANCELLATION,
TASKDIALOG_BUTTON,
TaskDialogIndirect,
TASKDIALOG_COMMON_BUTTON_FLAGS,
TDCBF_YES_BUTTON,
TDCBF_NO_BUTTON,
TDCBF_OK_BUTTON,
TDCBF_CANCEL_BUTTON,
TaskDialogIndirect, TASKDIALOGCONFIG, TASKDIALOG_BUTTON,
TASKDIALOG_COMMON_BUTTON_FLAGS, TDCBF_CANCEL_BUTTON, TDCBF_NO_BUTTON,
TDCBF_OK_BUTTON, TDCBF_YES_BUTTON, TDF_ALLOW_DIALOG_CANCELLATION,
},
Foundation::BOOL,
};

let mut pf_verification_flag_checked = BOOL(0);
Expand All @@ -126,44 +105,35 @@ impl WinMessageDialog {
};

let (system_buttons, custom_buttons) = match self.opt.buttons {
MessageButtons::Ok => {
(TDCBF_OK_BUTTON, vec![])
},
MessageButtons::OkCancel => {
(
TASKDIALOG_COMMON_BUTTON_FLAGS(TDCBF_OK_BUTTON.0 | TDCBF_CANCEL_BUTTON.0),
vec![],
)
},
MessageButtons::YesNo => {
(
TASKDIALOG_COMMON_BUTTON_FLAGS(TDCBF_YES_BUTTON.0 | TDCBF_NO_BUTTON.0),
vec![],
)
},
MessageButtons::OkCustom(ok_text) => {
(
Default::default(),
vec![
(id_custom_ok, str_to_vec_u16(&ok_text)),
],
)
},
MessageButtons::OkCancelCustom(ok_text, cancel_text) => {
(
Default::default(),
vec![
(id_custom_ok, str_to_vec_u16(&ok_text)),
(id_custom_cancel, str_to_vec_u16(&cancel_text)),
],
)
},
MessageButtons::Ok => (TDCBF_OK_BUTTON, vec![]),
MessageButtons::OkCancel => (
TASKDIALOG_COMMON_BUTTON_FLAGS(TDCBF_OK_BUTTON.0 | TDCBF_CANCEL_BUTTON.0),
vec![],
),
MessageButtons::YesNo => (
TASKDIALOG_COMMON_BUTTON_FLAGS(TDCBF_YES_BUTTON.0 | TDCBF_NO_BUTTON.0),
vec![],
),
MessageButtons::OkCustom(ok_text) => (
Default::default(),
vec![(id_custom_ok, str_to_vec_u16(&ok_text))],
),
MessageButtons::OkCancelCustom(ok_text, cancel_text) => (
Default::default(),
vec![
(id_custom_ok, str_to_vec_u16(&ok_text)),
(id_custom_cancel, str_to_vec_u16(&cancel_text)),
],
),
};

let p_buttons = custom_buttons.iter().map(|(id, text)| TASKDIALOG_BUTTON {
nButtonID: *id,
pszButtonText: PCWSTR(text.as_ptr()),
}).collect::<Vec<_>>();
let p_buttons = custom_buttons
.iter()
.map(|(id, text)| TASKDIALOG_BUTTON {
nButtonID: *id,
pszButtonText: PCWSTR(text.as_ptr()),
})
.collect::<Vec<_>>();
task_dialog_config.dwCommonButtons = system_buttons;
task_dialog_config.pButtons = p_buttons.as_ptr();
task_dialog_config.cButtons = custom_buttons.len() as u32;
Expand All @@ -177,11 +147,7 @@ impl WinMessageDialog {
)
};

ret.is_ok() && (
pn_button == id_custom_ok
|| pn_button == IDYES.0
|| pn_button == IDOK.0
)
ret.is_ok() && (pn_button == id_custom_ok || pn_button == IDYES.0 || pn_button == IDOK.0)
}

#[cfg(not(feature = "common-controls-v6"))]
Expand Down
6 changes: 4 additions & 2 deletions src/backend/xdg_desktop_portal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@ fn add_filters_to_save_file_options(

// refer to https://github.com/flatpak/xdg-desktop-portal/issues/213
fn uri_to_pathbuf(uri: &str) -> Option<PathBuf> {
urlencoding::decode(uri).ok()?
.strip_prefix("file://").map(PathBuf::from)
urlencoding::decode(uri)
.ok()?
.strip_prefix("file://")
.map(PathBuf::from)
}

fn ok_or_warn<T, E: std::fmt::Debug>(result: Result<T, E>) -> Option<T> {
Expand Down
13 changes: 13 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,22 @@
//! to [spawn on main and await in other thread](https://github.com/PolyMeilex/rfd/blob/master/examples/async.rs).
//! Non-windowed apps will never be able to spawn async dialogs or from threads other than the main thread.
//!
//! # Customize button texts of message dialog in Windows
//!
//! `TaskDialogIndirect` API is used for showing message dialog which can have customized button texts.
//! It is only provided by ComCtl32.dll v6 but Windows use v5 by default.
//! If you want to customize button texts or just need a modern dialog style (aka *visual styles*), you will need to:
//!
//! 1. Enable cargo feature `common-controls-v6`.
//! 2. Add an application manifest to use ComCtl32.dll v5. See [Windows Controls / Enabling Visual Styles](https://docs.microsoft.com/en-us/windows/win32/controls/cookbook-overview)
//!
//!
//! Here is an [example](https://github.com/PolyMeilex/rfd/tree/master/examples/message-custom-buttons) using [embed-resource](https://docs.rs/embed-resource/latest/embed_resource/).
//!
//! # Cargo features
//! * `gtk3`: Uses GTK for dialogs on Linux & BSDs; has no effect on Windows and macOS
//! * `xdg-portal`: Uses XDG Desktop Portal instead of GTK on Linux & BSDs
//! * `common-controls-v6`: Use `TaskDialogIndirect` API from ComCtl32.dll v6 for showing message dialog. This is necessary if you need to customize dialog button texts.
//!
//! # State
//!
Expand Down
2 changes: 1 addition & 1 deletion src/message_dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ pub enum MessageButtons {
OkCustom(String),
/// Two customizable buttons.
/// Notice that in Windows, this only works with the feature *common-controls-v6* enabled
OkCancelCustom(String, String)
OkCancelCustom(String, String),
}

impl Default for MessageButtons {
Expand Down