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

windows: add builder method to make a tool window #4123

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions src/changelog/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ changelog entry.
- Added `Window::safe_area`, which describes the area of the surface that is unobstructed.
- On X11, Wayland, Windows and macOS, improved scancode conversions for more obscure key codes.
- Add ability to make non-activating window on macOS using `NSPanel` with `NSWindowStyleMask::NonactivatingPanel`.
- On Windows, add `WindowAttributesExtWindows::with_tool_window` to create a window with the `WS_EX_TOOLWINDOW` ex\_style.

### Changed

Expand Down
9 changes: 9 additions & 0 deletions src/platform/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,9 @@ pub trait WindowAttributesExtWindows {
/// Enabling the shadow causes a thin 1px line to appear on the top of the window.
fn with_undecorated_shadow(self, shadow: bool) -> Self;

/// whether to apply WS_EX_TOOLWINDOW to both hide window from taskbar and remove animations
fn with_tool_window(self, tool_window: bool) -> Self;

/// Sets system-drawn backdrop type.
///
/// Requires Windows 11 build 22523+.
Expand Down Expand Up @@ -581,6 +584,12 @@ impl WindowAttributesExtWindows for WindowAttributes {
self
}

#[inline]
fn with_tool_window(mut self, tool_window: bool) -> Self {
self.platform_specific.tool_window = tool_window;
self
}

#[inline]
fn with_system_backdrop(mut self, backdrop_type: BackdropType) -> Self {
self.platform_specific.backdrop_type = backdrop_type;
Expand Down
2 changes: 2 additions & 0 deletions src/platform_impl/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub struct PlatformSpecificWindowAttributes {
pub skip_taskbar: bool,
pub class_name: String,
pub decoration_shadow: bool,
pub tool_window: bool,
pub backdrop_type: BackdropType,
pub clip_children: bool,
pub border_color: Option<Color>,
Expand All @@ -44,6 +45,7 @@ impl Default for PlatformSpecificWindowAttributes {
skip_taskbar: false,
class_name: "Window Class".to_string(),
decoration_shadow: false,
tool_window: false,
backdrop_type: BackdropType::default(),
clip_children: true,
border_color: None,
Expand Down
5 changes: 5 additions & 0 deletions src/platform_impl/windows/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,11 @@ unsafe fn init(
None => fallback_parent(),
};

if attributes.platform_specific.tool_window {
window_flags.set(WindowFlags::TOOL, true);
window_flags.set(WindowFlags::ON_TASKBAR, false);
}

let menu = attributes.platform_specific.menu;
let fullscreen = attributes.fullscreen.clone();
let maximized = attributes.maximized;
Expand Down
30 changes: 18 additions & 12 deletions src/platform_impl/windows/window_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ use windows_sys::Win32::UI::WindowsAndMessaging::{
SW_HIDE, SW_MAXIMIZE, SW_MINIMIZE, SW_RESTORE, SW_SHOW, SW_SHOWNOACTIVATE, WINDOWPLACEMENT,
WINDOW_EX_STYLE, WINDOW_STYLE, WS_BORDER, WS_CAPTION, WS_CHILD, WS_CLIPCHILDREN,
WS_CLIPSIBLINGS, WS_EX_ACCEPTFILES, WS_EX_APPWINDOW, WS_EX_LAYERED, WS_EX_NOREDIRECTIONBITMAP,
WS_EX_TOPMOST, WS_EX_TRANSPARENT, WS_EX_WINDOWEDGE, WS_MAXIMIZE, WS_MAXIMIZEBOX, WS_MINIMIZE,
WS_MINIMIZEBOX, WS_OVERLAPPEDWINDOW, WS_POPUP, WS_SIZEBOX, WS_SYSMENU, WS_VISIBLE,
WS_EX_TOOLWINDOW, WS_EX_TOPMOST, WS_EX_TRANSPARENT, WS_EX_WINDOWEDGE, WS_MAXIMIZE,
WS_MAXIMIZEBOX, WS_MINIMIZE, WS_MINIMIZEBOX, WS_OVERLAPPEDWINDOW, WS_POPUP, WS_SIZEBOX,
WS_SYSMENU, WS_VISIBLE,
};

use crate::dpi::{PhysicalPosition, PhysicalSize, Size};
Expand Down Expand Up @@ -97,33 +98,34 @@ bitflags! {
const CHILD = 1 << 10;
const MAXIMIZED = 1 << 11;
const POPUP = 1 << 12;
const TOOL = 1 << 13;

/// Marker flag for fullscreen. Should always match `WindowState::fullscreen`, but is
/// included here to make masking easier.
const MARKER_EXCLUSIVE_FULLSCREEN = 1 << 13;
const MARKER_BORDERLESS_FULLSCREEN = 1 << 14;
const MARKER_EXCLUSIVE_FULLSCREEN = 1 << 14;
const MARKER_BORDERLESS_FULLSCREEN = 1 << 15;

/// The `WM_SIZE` event contains some parameters that can effect the state of `WindowFlags`.
/// In most cases, it's okay to let those parameters change the state. However, when we're
/// running the `WindowFlags::apply_diff` function, we *don't* want those parameters to
/// effect our stored state, because the purpose of `apply_diff` is to update the actual
/// window's state to match our stored state. This controls whether to accept those changes.
const MARKER_RETAIN_STATE_ON_SIZE = 1 << 15;
const MARKER_RETAIN_STATE_ON_SIZE = 1 << 16;

const MARKER_IN_SIZE_MOVE = 1 << 16;
const MARKER_IN_SIZE_MOVE = 1 << 17;

const MINIMIZED = 1 << 17;
const MINIMIZED = 1 << 18;

const IGNORE_CURSOR_EVENT = 1 << 18;
const IGNORE_CURSOR_EVENT = 1 << 19;

/// Fully decorated window (incl. caption, border and drop shadow).
const MARKER_DECORATIONS = 1 << 19;
const MARKER_DECORATIONS = 1 << 20;
/// Drop shadow for undecorated windows.
const MARKER_UNDECORATED_SHADOW = 1 << 20;
const MARKER_UNDECORATED_SHADOW = 1 << 21;

const MARKER_ACTIVATE = 1 << 21;
const MARKER_ACTIVATE = 1 << 22;

const CLIP_CHILDREN = 1 << 22;
const CLIP_CHILDREN = 1 << 23;

const EXCLUSIVE_FULLSCREEN_OR_MASK = WindowFlags::ALWAYS_ON_TOP.bits();
}
Expand Down Expand Up @@ -292,6 +294,10 @@ impl WindowFlags {
if self.contains(WindowFlags::POPUP) {
style |= WS_POPUP;
}
if self.contains(WindowFlags::TOOL) {
style &= !WS_OVERLAPPEDWINDOW;
style_ex |= WS_EX_TOOLWINDOW;
}
if self.contains(WindowFlags::MINIMIZED) {
style |= WS_MINIMIZE;
}
Expand Down
Loading