Skip to content

Commit

Permalink
Make drag and drop optional (fixes OleInitialize failure #1255) (#1524)
Browse files Browse the repository at this point in the history
Co-authored-by: Osspial <osspial@gmail.com>
  • Loading branch information
chemicstry and Osspial authored Jun 28, 2020
1 parent 2191e9e commit b1e22aa
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 6 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
- On Unix, X11 and Wayland are now optional features (enabled by default)
- On X11, fix deadlock when calling `set_fullscreen_inner`.
- On Web, prevent the webpage from scrolling when the user is focused on a winit canvas

- On Windows, drag and drop is now optional and must be enabled with `WindowBuilderExtWindows::with_drag_and_drop(true)`.
- On Wayland, fix deadlock when calling to `set_inner_size` from a callback.
- On macOS, add `hide__other_applications` to `EventLoopWindowTarget` via existing `EventLoopWindowTargetExtMacOS` trait. `hide_other_applications` will hide other applications by calling `-[NSApplication hideOtherApplications: nil]`.
- On android added support for `run_return`.
Expand All @@ -23,6 +23,7 @@
- On Web, replaced zero timeout for `ControlFlow::Poll` with `requestAnimationFrame`
- On Web, fix a possible panic during event handling
- On macOS, fix `EventLoopProxy` leaking memory for every instance.
- On Windows, drag and drop can now be disabled with `WindowBuilderExtWindows::with_drag_and_drop(false)`.

# 0.22.0 (2020-03-09)

Expand Down
14 changes: 14 additions & 0 deletions src/platform/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion src/platform_impl/windows/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down
14 changes: 13 additions & 1 deletion src/platform_impl/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
Expand Down
13 changes: 10 additions & 3 deletions src/platform_impl/windows/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand All @@ -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();
Expand All @@ -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 {
Expand Down

0 comments on commit b1e22aa

Please sign in to comment.