On Windows, allow the creation of popup window (#1895)

Add with_owner_window to WindowBuilderExtWindows.
Add set_enable to WindowExtWindows.
This commit is contained in:
Rodrigodd 2021-04-10 10:47:19 -03:00 committed by GitHub
parent 629cd86c7c
commit dabcb1834d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 80 additions and 11 deletions

View file

@ -15,9 +15,16 @@ use crate::event::DeviceId as RootDeviceId;
use crate::icon::Icon;
use crate::window::Theme;
#[derive(Clone)]
pub enum Parent {
None,
ChildOf(HWND),
OwnedBy(HWND),
}
#[derive(Clone)]
pub struct PlatformSpecificWindowBuilderAttributes {
pub parent: Option<HWND>,
pub parent: Parent,
pub menu: Option<HMENU>,
pub taskbar_icon: Option<Icon>,
pub no_redirection_bitmap: bool,
@ -28,7 +35,7 @@ pub struct PlatformSpecificWindowBuilderAttributes {
impl Default for PlatformSpecificWindowBuilderAttributes {
fn default() -> Self {
Self {
parent: None,
parent: Parent::None,
menu: None,
taskbar_icon: None,
no_redirection_bitmap: false,

View file

@ -44,7 +44,7 @@ use crate::{
icon::{self, IconType},
monitor, util,
window_state::{CursorFlags, SavedWindow, WindowFlags, WindowState},
PlatformSpecificWindowBuilderAttributes, WindowId,
Parent, PlatformSpecificWindowBuilderAttributes, WindowId,
},
window::{CursorIcon, Fullscreen, Theme, UserAttentionType, WindowAttributes},
};
@ -733,12 +733,24 @@ unsafe fn init<T: 'static>(
window_flags.set(WindowFlags::TRANSPARENT, attributes.transparent);
// WindowFlags::VISIBLE and MAXIMIZED are set down below after the window has been configured.
window_flags.set(WindowFlags::RESIZABLE, attributes.resizable);
window_flags.set(WindowFlags::CHILD, pl_attribs.parent.is_some());
window_flags.set(WindowFlags::ON_TASKBAR, true);
if pl_attribs.parent.is_some() && pl_attribs.menu.is_some() {
warn!("Setting a menu on windows that have a parent is unsupported");
}
let parent = match pl_attribs.parent {
Parent::ChildOf(parent) => {
window_flags.set(WindowFlags::CHILD, true);
if pl_attribs.menu.is_some() {
warn!("Setting a menu on a child window is unsupported");
}
Some(parent)
}
Parent::OwnedBy(parent) => {
window_flags.set(WindowFlags::POPUP, true);
Some(parent)
}
Parent::None => {
window_flags.set(WindowFlags::ON_TASKBAR, true);
None
}
};
// creating the real window this time, by using the functions in `extra_functions`
let real_window = {
@ -752,7 +764,7 @@ unsafe fn init<T: 'static>(
winuser::CW_USEDEFAULT,
winuser::CW_USEDEFAULT,
winuser::CW_USEDEFAULT,
pl_attribs.parent.unwrap_or(ptr::null_mut()),
parent.unwrap_or(ptr::null_mut()),
pl_attribs.menu.unwrap_or(ptr::null_mut()),
libloaderapi::GetModuleHandleW(ptr::null()),
ptr::null_mut(),

View file

@ -68,6 +68,7 @@ bitflags! {
const TRANSPARENT = 1 << 6;
const CHILD = 1 << 7;
const MAXIMIZED = 1 << 8;
const POPUP = 1 << 14;
/// Marker flag for fullscreen. Should always match `WindowState::fullscreen`, but is
/// included here to make masking easier.
@ -213,6 +214,9 @@ impl WindowFlags {
if self.contains(WindowFlags::CHILD) {
style |= WS_CHILD; // This is incompatible with WS_POPUP if that gets added eventually.
}
if self.contains(WindowFlags::POPUP) {
style |= WS_POPUP;
}
if self.contains(WindowFlags::MINIMIZED) {
style |= WS_MINIMIZE;
}