Make drag and drop optional (fixes OleInitialize failure #1255) (#1524)

Co-authored-by: Osspial <osspial@gmail.com>
This commit is contained in:
Jurgis 2020-06-29 01:17:27 +03:00 committed by GitHub
parent 2191e9ecd5
commit b1e22aa559
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 40 additions and 6 deletions

View file

@ -117,6 +117,14 @@ pub trait WindowBuilderExtWindows {
/// This sets `WS_EX_NOREDIRECTIONBITMAP`.
fn with_no_redirection_bitmap(self, flag: bool) -> WindowBuilder;
/// Enables or disables drag and drop support (enabled by default). Will interfere with other crates
/// that use multi-threaded COM API (`CoInitializeEx` with `COINIT_MULTITHREADED` instead of
/// `COINIT_APARTMENTTHREADED`) on the same thread. Note that winit may still attempt to initialize
/// COM API regardless of this option. Currently only fullscreen mode does that, but there may be more in the future.
/// If you need COM API with `COINIT_MULTITHREADED` you must initialize it before calling any winit functions.
/// See https://docs.microsoft.com/en-us/windows/win32/api/objbase/nf-objbase-coinitialize#remarks for more information.
fn with_drag_and_drop(self, flag: bool) -> WindowBuilder;
}
impl WindowBuilderExtWindows for WindowBuilder {
@ -137,6 +145,12 @@ impl WindowBuilderExtWindows for WindowBuilder {
self.platform_specific.no_redirection_bitmap = flag;
self
}
#[inline]
fn with_drag_and_drop(mut self, flag: bool) -> WindowBuilder {
self.platform_specific.drag_and_drop = flag;
self
}
}
/// Additional methods on `MonitorHandle` that are specific to Windows.

View file

@ -82,7 +82,7 @@ lazy_static! {
pub(crate) struct SubclassInput<T: 'static> {
pub window_state: Arc<Mutex<WindowState>>,
pub event_loop_runner: EventLoopRunnerShared<T>,
pub file_drop_handler: FileDropHandler,
pub file_drop_handler: Option<FileDropHandler>,
}
impl<T> SubclassInput<T> {

View file

@ -14,11 +14,23 @@ pub use self::icon::WinIcon as PlatformIcon;
use crate::event::DeviceId as RootDeviceId;
use crate::icon::Icon;
#[derive(Clone, Default)]
#[derive(Clone)]
pub struct PlatformSpecificWindowBuilderAttributes {
pub parent: Option<HWND>,
pub taskbar_icon: Option<Icon>,
pub no_redirection_bitmap: bool,
pub drag_and_drop: bool,
}
impl Default for PlatformSpecificWindowBuilderAttributes {
fn default() -> Self {
Self {
parent: None,
taskbar_icon: None,
no_redirection_bitmap: false,
drag_and_drop: true,
}
}
}
unsafe impl Send for PlatformSpecificWindowBuilderAttributes {}

View file

@ -70,8 +70,9 @@ impl Window {
//
// done. you owe me -- ossi
unsafe {
let drag_and_drop = pl_attr.drag_and_drop;
init(w_attr, pl_attr, event_loop).map(|win| {
let file_drop_handler = {
let file_drop_handler = if drag_and_drop {
use winapi::shared::winerror::{OLE_E_WRONGCOMPOBJ, RPC_E_CHANGED_MODE, S_OK};
let ole_init_result = ole2::OleInitialize(ptr::null_mut());
@ -80,7 +81,11 @@ impl Window {
if ole_init_result == OLE_E_WRONGCOMPOBJ {
panic!("OleInitialize failed! Result was: `OLE_E_WRONGCOMPOBJ`");
} else if ole_init_result == RPC_E_CHANGED_MODE {
panic!("OleInitialize failed! Result was: `RPC_E_CHANGED_MODE`");
panic!(
"OleInitialize failed! Result was: `RPC_E_CHANGED_MODE`. \
Make sure other crates are not using multithreaded COM library \
on the same thread or disable drag and drop support."
);
}
let file_drop_runner = event_loop.runner_shared.clone();
@ -99,7 +104,9 @@ impl Window {
ole2::RegisterDragDrop(win.window.0, handler_interface_ptr),
S_OK
);
file_drop_handler
Some(file_drop_handler)
} else {
None
};
let subclass_input = event_loop::SubclassInput {