Skip to content

Commit

Permalink
Respect starting directory for dialogs on Windows (#1452)
Browse files Browse the repository at this point in the history
* Respect starting directory for dialogs on Windows

Before this change, FileDialogOptions::starting_directory had not been
used on Windows and therefore had no influence on the starting directory
of a FileDialog window.

This has now been fixed.

The use of `SHCreateItemFromParsingName` makes it mandatory to
explicitly link against shell32.lib because this is not done
automatically since Rust 1.33.0.

See rust-lang/rust#56568 for details.

* Fix: Use winapi feature instead of build.rs

As it turns out, the winapi crate already exposes shell32.lib via a
cargo feature, so there is no need to link it manually.
  • Loading branch information
MaximilianKoestler authored Dec 16, 2020
1 parent 5e2f821 commit f4b98bd
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 1 deletion.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ Andrey Kabylin
Garrett Risley
Robert Wittams
Jaap Aarts
Maximilian Köstler
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ You can find its changes [documented below](#060---2020-06-01).
- `TextBox::with_text_alignment` and `TextBox::set_text_alignment` ([#1371] by [@cmyr])
- Add default minimum size to `WindowConfig`. ([#1438] by [@colinfruit])
- Open and save dialogs send configurable commands. ([#1463] by [@jneem])
- Windows: Dialogs now respect the parameter passed to `force_starting_directory()` ([#1452] by [@MaximilianKoestler])

### Changed

Expand Down Expand Up @@ -364,6 +365,7 @@ Last release without a changelog :(
[@colinfruit]: https://github.com/colinfruit
[@Maan2003]: https://github.com/Maan2003
[@derekdreery]: https://github.com/derekdreery
[@MaximilianKoestler]: https://github.com/MaximilianKoestler

[#599]: https://github.com/linebender/druid/pull/599
[#611]: https://github.com/linebender/druid/pull/611
Expand Down Expand Up @@ -553,6 +555,7 @@ Last release without a changelog :(
[#1441]: https://github.com/linebender/druid/pull/1441
[#1448]: https://github.com/linebender/druid/pull/1448
[#1463]: https://github.com/linebender/druid/pull/1463
[#1452]: https://github.com/linebender/druid/pull/1452

[Unreleased]: https://github.com/linebender/druid/compare/v0.6.0...master
[0.6.0]: https://github.com/linebender/druid/compare/v0.5.0...v0.6.0
Expand Down
3 changes: 2 additions & 1 deletion druid-shell/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ wio = "0.2.2"
version = "0.3.9"
features = ["d2d1_1", "dwrite", "winbase", "libloaderapi", "errhandlingapi", "winuser",
"shellscalingapi", "shobjidl", "combaseapi", "synchapi", "dxgi1_3", "dcomp",
"d3d11", "dwmapi", "wincon", "fileapi", "processenv", "winbase", "handleapi"]
"d3d11", "dwmapi", "wincon", "fileapi", "processenv", "winbase", "handleapi",
"shellapi"]

[target.'cfg(target_os="macos")'.dependencies]
block = "0.1.6"
Expand Down
16 changes: 16 additions & 0 deletions druid-shell/src/platform/windows/dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use std::convert::TryInto;
use std::ffi::OsString;
use std::ptr::null_mut;

use winapi::ctypes::c_void;
use winapi::shared::minwindef::*;
use winapi::shared::ntdef::LPWSTR;
use winapi::shared::windef::*;
Expand Down Expand Up @@ -147,6 +148,21 @@ pub(crate) unsafe fn get_file_dialog_path(

as_result(file_dialog.SetOptions(flags))?;

// set a starting directory
if let Some(path) = options.starting_directory {
let mut item: *mut IShellItem = null_mut();
if let Err(err) = as_result(SHCreateItemFromParsingName(
path.as_os_str().to_wide().as_ptr(),
null_mut(),
&IShellItem::uuidof(),
&mut item as *mut *mut IShellItem as *mut *mut c_void,
)) {
log::warn!("Failed to convert path: {}", err.to_string());
} else {
as_result(file_dialog.SetDefaultFolder(item))?;
}
}

// show the dialog
as_result(file_dialog.Show(hwnd_owner))?;
let mut result_ptr: *mut IShellItem = null_mut();
Expand Down

0 comments on commit f4b98bd

Please sign in to comment.